package org.example.core.storage.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.Data;
import org.example.common.utils.CharUtil;
import org.example.common.utils.DateTimeUtil;
import org.example.core.storage.Storage;
import org.example.db.entity.ObjectStorage;
import org.example.db.mapper.ObjectStorageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.InputStream;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

@Data
public class StorageService {

    private String active;
    private Storage storage;

    @Autowired
    ObjectStorageMapper objectStorageMapper;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    /**
     * 存储一个文件对象
     *
     * @param inputStream   文件输入流
     * @param contentLength 文件长度
     * @param contentType   文件类型
     * @param fileName      文件索引名
     */
    public ObjectStorage store(InputStream inputStream, long contentLength, String contentType, String fileName) {
        String key = generateKey(fileName);
        storage.store(inputStream, contentLength, contentType, key);

        String url = generateUrl(key);
        ObjectStorage objectStorage = new ObjectStorage();
        objectStorage.setName(fileName);
        objectStorage.setSize((int) contentLength);
        objectStorage.setType(contentType);
        objectStorage.setObjectKey(key);
        objectStorage.setUrl(url);
        objectStorage.setAddTime(DateTimeUtil.getDateTimeString());
        objectStorage.setUpdateTime(DateTimeUtil.getDateTimeString());
        objectStorageMapper.insert(objectStorage);

        return objectStorage;
    }

    private String generateKey(String originalFilename) {
        int index = originalFilename.lastIndexOf('.');
        String suffix = originalFilename.substring(index);

        String numberDateTimeString = DateTimeUtil.getNumberDateTimeString();
        Long increment = redisTemplate.opsForValue().increment("uniqueIncrement:" + numberDateTimeString, 1);
        redisTemplate.expire("uniqueIncrement:" + numberDateTimeString, 5, TimeUnit.SECONDS);
        String uniqueStr = numberDateTimeString + String.format("%1$06d", increment);

        return uniqueStr + suffix;
    }

    public Stream<Path> loadAll() {
        return storage.loadAll();
    }

    public Path load(String keyName) {
        return storage.load(keyName);
    }

    public Resource loadAsResource(String keyName) {
        return storage.loadAsResource(keyName);
    }

    public void delete(String keyName) {
        storage.delete(keyName);
    }

    private String generateUrl(String keyName) {
        return storage.generateUrl(keyName);
    }

    public ObjectStorage findByKey(String key){
        return objectStorageMapper.selectList(new LambdaQueryWrapper<ObjectStorage>().eq(ObjectStorage::getObjectKey, key)).get(0);
    }
}
